package com.cma.util;

import org.apache.commons.lang.StringUtils;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author hbb
 * @Date 2017/1/15 14:36
 */
public class ExcelUtil {
    /**
     * 生成excel文档通用方法
     * @param fields  传递的字段 集合
     * @param fieldName 传递的 字段对应中文名称集合
     * @param data 数据来源
     * @param <V> 数据类型
     * @return
     */
    public static <V> Object exportExc(String[] fields, Map<String,String> fieldName, List<V> data) {
        //创建工作表
        HSSFWorkbook wb = new HSSFWorkbook();
        //创建一个工作表sheet
        HSSFSheet sheet = wb.createSheet();
        //1，创建excel的第一行：表头			（这是第一行）
        HSSFRow row = sheet.createRow(0);
        //冻结表头（标题栏）
        sheet.createFreezePane(0, 1);
        HSSFCell cell = null;
        //定义颜色
        HSSFFont font = wb.createFont();
        font.setColor(new HSSFColor.RED().getIndex());
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            //设置行的宽度
            sheet.setColumnWidth(i, 8000);
            //创建第几列
            cell = row.createCell(i);
            //需要设置 的值
            String titleName = field;
            if(StringUtils.isNotBlank(fieldName.get(field))){
                titleName = fieldName.get(field);
            }
            HSSFRichTextString ts= new HSSFRichTextString(titleName);
            if(titleName.substring(0, 1).equals("*")){
                ts.applyFont(0, titleName.length(), font);
            }
            cell.setCellValue(ts);
            //cell.setCellValue(titleName);
            //将sheet定义为文本类型（这里是按fields的长度来定义 sheet的列数的）.这样，excel上的数据，就都是文本类型的！
            HSSFCellStyle cellStyle2 = wb.createCellStyle();
            cellStyle2.setDataFormat((short) 49);
            sheet.setDefaultColumnStyle(i,cellStyle2);//文本格式);
        }
        //2，创建excel的第二行：数据			（这是第二行）
        if(!data.isEmpty()){
            //追加数据（从第二行开始）
            for (int i = 0; i <data.size(); i++) {
                HSSFRow nextrow = sheet.createRow(i+1);
                //得到这一行后，从第一行 开始赋值
                HSSFCell cell2 = nextrow.createCell(0);
                V v = data.get(i);
                Class<? extends Object> myClass = v.getClass();
                for (int j = 0; j < fields.length; j++) {
                    //先通过反射，得到getter()
                    String getter = "get"+pareMethodName(fields[j]);
                    //这里使用try机制并且抛出，是为了：只要有一个错误，则不再会往下执行
                    try {
                        //先通过反射，调用getter()，通过有参构造方法得到对像的Method对像（这个对像里有相应的invoke()）得到属性数据
                        Method method = myClass.getMethod(getter, new Class[]{});
                        Object value = method.invoke(v, new Object[]{});
                        //通过getter()得到对像属性的数据类型后，再按照数据类型，把数据库里的数据转换过来。展示到excel里（特别是的时间类型的属性）
                        Type type = method.getGenericReturnType();
                        //每次，生成一个cell并且赋值（是每一次，都生成一个cell单元格）。再对单元格进行赋值
                        cell2 = nextrow.createCell(j);
                        //如果对像属性是时间类型，则需要转换
                        if(type == java.util.Date.class){
                            //数据库默认接收的时间类型是：yyyy-MM-dd
                            if(!org.springframework.util.StringUtils.isEmpty(value)){
                                String date = DateUtils.getDate((Date) value);
                                cell2.setCellValue(date);
                            }
                        }
                        else if(type==java.math.BigDecimal.class){

                            if(!org.springframework.util.StringUtils.isEmpty(value)){
                                    DecimalFormat df = new DecimalFormat("0.0000");
                                    String s=df.format(value);
                                    cell2.setCellValue(s);
                            }
                        }
                        else{
                            //使用三元运算，将null对像给去除
                            cell2.setCellValue(value == null ? "" : value+"");
                        }
                    } catch (Exception e) {

                    }
                }
            }
        }
        return wb;
    }
    public static String pareMethodName(String fldname){
        if(null == fldname || "".equals(fldname)){
            return " ";
        }
        return fldname.substring(0,1).toUpperCase()+fldname.substring(1);
    }

}
